package com.ccl.iot.device;

import com.ccl.iot.IOTDataType;
import com.ccl.iot.IOTObject;
import com.ccl.iot.IOTStateMonitor;
import com.ccl.iot.object.IOTDeviceInfoEx;
import com.ccl.iot.publics.ConvertFunctions;

public abstract class IOTDeviceWithState extends IOTDevice implements IOTObject.IOTMultiStateObject {

    protected int iStateAddress;

    protected int iState = 0;

    private String mUdid = null;

    private IOTStateMonitor iStateMonitor = new IOTStateMonitor(this);

    private IOTStateChangeListener stateChangeListener;

    public IOTDeviceWithState(long aDevID, IOTDeviceInfoEx aDeviceInfo, int aStateAddress, int aStateSize) {
        super(aDevID, aDeviceInfo, aStateAddress, aStateSize);
        setStateAddress(aStateAddress);
    }

    protected void setStateAddress(int aStateAddress) {
        iStateAddress = aStateAddress;

        mDefIndex = (iStateAddress - IOTDeviceConst.TDEVREG_ADDRESS.EDEVREG_ADDRESS_STATE_1);

        if (mDefIndex > 0) {
            mDefIndex /= IOTDeviceConst.TDEVREG_SIZE.EDEVREG_SIZE_STATE;
        }
        mDefIndex++;
    }

    @Override
    public String getUDID() {
        if(mUdid == null){
            mUdid = super.getUDID() + "@" + mDefIndex;
        }
        return mUdid;
    }

    @Override
    public int getState() {
        return iState;
    }

    @Override
    public byte[] getRegister() {
        return ConvertFunctions.UInt2ByteArray(iState);
    }

    protected void afterStateChange() {
        iStateMonitor.onStatusChange(iState);
        if (stateChangeListener != null){
            stateChangeListener.onStateChanged(this,0);
        }
    }

    @Override
    public void updateRegister(int aAddress, int aSize, byte[] aData, int aDataPos, int aNetWork, long time) {
        if (aAddress == getRegisterAddress() && aSize == getRegisterSize()) {
            iState = IOTDataType.C32(aData, aDataPos);
            afterStateChange();
        }else if(aAddress == 0){
            iState = IOTDataType.C32(aData, aDataPos+getRegisterAddress());
            afterStateChange();
        }
    }

    @Override
    public String getStateID() {
        return String.valueOf(iState);
    }

    @Override
    public boolean setState(int aNewState) {
        return setState(aNewState, -1);
    }

    public boolean setState(int aNewState, int netWorkState) {

        if (iRegisterInterface != null) {
            byte tState[] = IOTDataType.C8Array(aNewState);

            iRegisterInterface.writeRegister(this, tState, netWorkState);
        } else {
            iState = aNewState;

            afterStateChange();
        }
        return false;
    }

    @Override
    public boolean addStateChangeListener(IOTStateChangeListener aListener) {
        return iStateMonitor.addStateChangeListener(aListener);
    }

    public void setStateChangeListener(IOTStateChangeListener listener) {
        stateChangeListener = listener;
    }

    @Override
    public boolean removeStateChangeListener(IOTStateChangeListener aListener) {
        return iStateMonitor.removeStateChangeListener(aListener);
    }

    @Override
    public void addListener(IOTListener aListener) {
        super.addListener(aListener);

        if (aListener != null && aListener instanceof IOTStateChangeListener) {
            addStateChangeListener((IOTStateChangeListener) aListener);
        }
    }

    @Override
    public void removeAllListeners(IOTListener aListener) {
        super.removeAllListeners(aListener);

        if (aListener != null && aListener instanceof IOTStateChangeListener) {
            removeStateChangeListener((IOTStateChangeListener) aListener);
        }
    }

}
